/* enum */
import Field from '@model/entity/Field'
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
/* model */
import { getFields, RoleViewFormFieldNameEnum } from '@src/modules/account/roleModule/component/RoleViewForm/model'
/* hooks */
import { useStoreCurrentSelectRole, useStoreMode } from '@src/modules/account/roleModule/store/hooks'
/* scss */
import '@src/modules/account/roleModule/component/RoleViewForm/index.scss'
/* vue */
import { ComponentInstance, defineComponent, reactive, toRefs, toRef, ref, Ref, computed, watch, nextTick } from 'vue'
/* service */
import roleModule from '@service/RoleService'
/* util */
import { findComponentsDownward } from '@src/util/assist'
import { isNotEmpty } from '@src/util/type'
import QualificationManagementField from '@src/component/common/BaseSelectUser/components/Form/QualificationManagementField.tsx'

type RoleViewFormFieldUpdateResultType = {
  field: Field;
  newValue: string;
  oldValue: string;
}

export type RoleViewFormModelType = {
  [fieldName: string]: string;
  [RoleViewFormFieldNameEnum.Name]: string;
  [RoleViewFormFieldNameEnum.Description]: string;
}

export type RoleViewFormProps = {

}

export interface RoleViewFormSetupState {
  outsideGetForm: () => RoleViewFormModelType;
  validate: () => Promise<boolean>;
}

export enum RoleViewFormEventEnum {
  Input = 'input'
}

export type RoleViewFormEmitsOptions = {
  input: () => void;
}

export type RoleViewFormInstance = ComponentInstance & RoleViewFormSetupState
export type RoleViewFormVM = RoleViewFormSetupState & RoleViewFormProps & ComponentInstance

export default defineComponent({
  name: ComponentNameEnum.RoleViewForm,
  emits: [
    RoleViewFormEventEnum.Input
  ],
  setup(props: RoleViewFormProps, { slots, emit }) {
    
    const { currentRoleName, currentRoleDescription, currentSelectRole, currentRoleId, currentQualificationIds } = useStoreCurrentSelectRole()
    const { mode } = useStoreMode()
    
    const FormBuilderComponent: Ref<any> = ref(null)
    
    let form: RoleViewFormModelType = reactive({
      name: currentRoleName.value,
      description: currentRoleDescription.value,
      qualificationIds :currentQualificationIds.value
    })
    
    watch(() => currentRoleName.value, (newValue) => {
      
      form.name = newValue
      
      setTimeout(() => {
        removeFormItemValidate()
      }, 500)
      
    })
    
    watch(() => currentRoleDescription.value, (newValue) => {
      form.description = newValue
    })
    
    const fields = computed(() => {
      const isDisabled = Boolean(roleModule.isSystemRole(currentSelectRole.value) && currentRoleId.value)
      return getFields(isDisabled)
    })
    
    function update(result: RoleViewFormFieldUpdateResultType) {
      form[result.field.fieldName] = result.newValue
    }
    
    function outsideGetForm() {
      return form
    }
    
    function validate() {
      
      if (FormBuilderComponent.value) {
        return FormBuilderComponent.value.validate(false)
      }
      
      return Promise.resolve(true)
    }
    
    function removeFormItemValidate() {
      
      const formItemComponents = findComponentsDownward(FormBuilderComponent.value, 'form-item')
      
      if (isNotEmpty(formItemComponents)) {
        formItemComponents.forEach((formItemComponent: Record<string, any>) => {
          formItemComponent.resetValidationStatus()
        })
      }
      
    }
    
    return {
      form,
      fields,
      update,
      outsideGetForm,
      validate,
      FormBuilderComponent
    }
    
  },
  render() {
    return (
      <div class={ComponentNameEnum.RoleViewForm}>
        <form-builder 
          ref='FormBuilderComponent'
          fields={this.fields} 
          value={this.form} 
          onUpdate={this.update}
          scopedSlots={{
            qualificationIds:(element)=>{
              return <QualificationManagementField class="mar-t-8" label={this.$t('qualificationManagement.view.label13')} value={this.form.qualificationIds} onInput={(val)=>this.update({field:element.field, newValue:val})} />
            }
          }}
        >
        </form-builder>
      </div>
    ) as any
  }
}) as any
